package com.zenithmind.chat.controller;

import com.zenithmind.chat.temp.Log;
import com.zenithmind.chat.temp.OperationTypeEnum;
import com.zenithmind.chat.pojo.dto.AiChatDTO;
import com.zenithmind.chat.pojo.dto.AiChatMessageDTO;
import com.zenithmind.chat.pojo.entity.AiChatMessage;
import com.zenithmind.chat.pojo.vo.AiChatVO;
import com.zenithmind.chat.service.AiChatService;
import com.zenithmind.chat.service.AiChatStreamService;
import com.zenithmind.chat.temp.Result;
import com.zenithmind.chat.temp.ResultCode;
import com.zenithmind.chat.temp.PageResult;
import com.zenithmind.chat.pojo.query.AiChatPageQuery;
import com.zenithmind.chat.temp.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.Map;

/**
 * AI对话控制器 - 重构后遵循单一职责原则
 * 只负责HTTP请求处理和响应，不包含业务逻辑和资源管理
 */
@Slf4j
@Tag(name = "AI对话接口")
@RestController
@RequestMapping("/api/zenithMind/aiChat")
public class AiChatController {

    // === 依赖注入 - 遵循依赖倒置原则，使用构造函数注入 ===
    private final AiChatService aiChatService;
    private final AiChatStreamService streamService;

    /**
     * 构造函数注入 - 遵循依赖倒置原则
     */
    public AiChatController(AiChatService aiChatService, AiChatStreamService streamService) {
        this.aiChatService = aiChatService;
        this.streamService = streamService;
    }
    
    /**
     * 创建AI对话
     *
     * @param chatDTO 对话信息
     * @return 对话ID
     */
    @Log(description = "创建AI对话", operationType = OperationTypeEnum.ADD)
    @Operation(summary = "创建AI对话")
    @PostMapping("/createChat")
    public Result<String> createChat(@RequestBody @Valid AiChatDTO chatDTO) {
        log.info("创建AI对话，请求参数详情：{}", chatDTO);
        return Result.success(aiChatService.createChat(chatDTO));
    }
    
    /**
     * 新增或更新AI对话
     * @param chatDTO 对话信息
     * @return 对话ID
     */
    @Log(description = "新增或更新AI对话", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "新增或更新AI对话")
    @PostMapping("/saveOrUpdateChat")
    public Result<String> saveOrUpdateChat(@RequestBody @Valid AiChatDTO chatDTO) {
        log.info("新增或更新AI对话：{}", chatDTO);
        return Result.success(aiChatService.saveOrUpdateChat(chatDTO));
    }
    
    /**
     * 发送消息 (旧的非流式接口，可以考虑标记为@Deprecated或移除)
     */
    @Log(description = "发送AI消息(非流式)", operationType = OperationTypeEnum.ADD)
    @Operation(summary = "发送消息 (非流式)")
    @PostMapping("/sendMessage_old/{chatId}") // 更改路径以区分
    public Result<AiChatMessage> sendMessageNonStream(@PathVariable String chatId, @RequestBody @Valid AiChatMessageDTO messageDTO) {
        if (messageDTO.getChatId() == null) {
            messageDTO.setChatId(chatId);
        } else if (!messageDTO.getChatId().equals(chatId)) {
            return Result.fail(ResultCode.PARAM_ERROR.getCode(), "Chat ID in path and body do not match.", null);
        }
        log.info("发送AI消息到对话 {}: {}", chatId, messageDTO);
        return Result.success(aiChatService.sendMessage(messageDTO)); // 调用旧的非流式service方法
    }
    
    /**
     * 发送消息并流式返回响应
     *
     * @param chatId 对话ID
     * @param messageDTO 消息信息
     * @return SseEmitter 用于流式响应
     */
    @Log(description = "发送AI消息(流式)", operationType = OperationTypeEnum.ADD)
    @Operation(summary = "发送消息 (流式)")
    @PostMapping(value = "/sendMessage/{chatId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter sendMessageStream(@PathVariable String chatId, @RequestBody @Valid AiChatMessageDTO messageDTO) {
        if (messageDTO.getChatId() == null) {
            messageDTO.setChatId(chatId);
        } else if (!messageDTO.getChatId().equals(chatId)) {
            // 对于流式端点，直接抛出异常或返回一个立即完成的错误emitter可能更合适
            SseEmitter errorEmitter = new SseEmitter(-1L); // 使用长超时或无超时
            try {
                errorEmitter.send(SseEmitter.event().name("error").data("Chat ID in path and body do not match."));
                errorEmitter.complete();
            } catch (java.io.IOException e) {
                log.error("发送SSE错误失败", e);
            }
            return errorEmitter;
        }
        log.info("开始流式发送AI消息到对话 {}: {}", chatId, messageDTO);

        // 获取当前用户ID
        String currentUserId = SecurityUtils.getCurrentUserId();

        // 使用专门的流式服务处理 - 遵循单一职责原则
        return streamService.sendMessageStream(messageDTO, currentUserId);
    }
    
    /**
     * 获取对话历史
     *
     * @param chatId 对话ID
     * @return 消息列表
     */
    @Log(description = "获取对话历史", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "获取对话历史")
    @GetMapping("/getChatHistory/{chatId}")
    public Result<List<AiChatMessage>> getChatHistory(@PathVariable String chatId) {
        log.info("获取AI对话历史：{}", chatId);
        List<AiChatMessage> chatHistory = aiChatService.getChatHistory(chatId);
        // 即使列表为空也返回成功，前端处理空列表
        return Result.success(chatHistory);
    }
    
    /**
     * 获取对话详情
     *
     * @param chatId 对话ID
     * @return 对话详情
     */
    @Log(description = "获取对话详情", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "获取对话详情")
    @GetMapping("/getChatDetail/{chatId}")
    public Result<AiChatVO> getChatDetail(@PathVariable String chatId) {
        log.info("获取AI对话详情：{}", chatId);
        AiChatVO chatDetail = aiChatService.getChatDetail(chatId);
        if (chatDetail == null) {
            // 对话不存在时返回空对象而不是null
            return Result.success(new AiChatVO());
        }
        return Result.success(chatDetail);
    }
    
    /**
     * 删除对话
     *
     * @param chatId 对话ID
     * @return 删除结果
     */
    @Log(description = "删除对话", operationType = OperationTypeEnum.DELETE)
    @Operation(summary = "删除对话")
    @DeleteMapping("/deleteChat/{chatId}")
    public Result<Void> deleteChat(@PathVariable String chatId) {
        log.info("删除AI对话：{}", chatId);
        aiChatService.deleteChat(chatId);
        return Result.success();
    }
    
    /**
     * 清空对话历史
     *
     * @param chatId 对话ID
     * @return 清空结果
     */
    @Log(description = "清空对话历史", operationType = OperationTypeEnum.DELETE)
    @Operation(summary = "清空对话历史")
    @DeleteMapping("/clearChatHistory/{chatId}")
    public Result<Void> clearChatHistory(@PathVariable String chatId) {
        log.info("清空AI对话历史：{}", chatId);
        aiChatService.clearChatHistory(chatId);
        return Result.success();
    }
    
    /**
     * 更新对话标题
     *
     * @param chatId 对话ID
     * @param title 标题
     * @return 更新结果
     */
    @Log(description = "更新对话标题", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "更新对话标题")
    @PutMapping("/updateChatTitle/{chatId}")
    public Result<Void> updateChatTitle(@PathVariable String chatId, @RequestParam String title) {
        log.info("更新AI对话标题：chatId={}, title={}", chatId, title);
        aiChatService.updateChatTitle(chatId, title);
        return Result.success();
    }
    
    /**
     * 更新系统提示词
     *
     * @param chatId 对话ID
     * @param systemPrompt 系统提示词
     * @return 更新结果
     */
    @Log(description = "更新系统提示词", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "更新系统提示词")
    @PutMapping("/updateSystemPrompt/{chatId}")
    public Result<Void> updateSystemPrompt(@PathVariable String chatId, @RequestParam String systemPrompt) {
        log.info("更新AI对话系统提示词：chatId={}, systemPrompt={}", chatId, systemPrompt);
        aiChatService.updateSystemPrompt(chatId, systemPrompt);
        return Result.success();
    }

    @Log(description = "分页获取AI对话列表", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "分页获取AI对话列表")
    @GetMapping("/getChatPage")
    public Result<PageResult<AiChatVO>> getChatPage(AiChatPageQuery query) {
        log.info("分页获取AI对话列表: query={}", query);
        PageResult<AiChatVO> pageResult = aiChatService.getChatPage(query);
        return Result.success(pageResult);
    }
    
    // =================== 管理平台接口 ===================
    
    /**
     * 管理平台-分页获取所有用户的AI对话列表
     *
     * @param query 查询条件
     * @return 分页结果
     */
    @Log(description = "管理平台-分页获取所有用户的AI对话列表", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "管理平台-分页获取所有用户的AI对话列表")
    @GetMapping("/getAllChatPage")
    public Result<PageResult<AiChatVO>> getAllChatPage(AiChatPageQuery query) {
        log.info("管理平台-分页获取所有用户的AI对话列表: query={}", query);
        // 调用service层方法，获取所有用户的对话记录
        PageResult<AiChatVO> pageResult = aiChatService.getAllChatPage(query);
        return Result.success(pageResult);
    }
    
    /**
     * 管理平台-批量删除AI对话
     *
     * @param ids AI对话ID列表
     * @return 删除结果
     */
    @Log(description = "管理平台-批量删除AI对话", operationType = OperationTypeEnum.DELETE)
    @Operation(summary = "管理平台-批量删除AI对话")
    @DeleteMapping("/batchDeleteChats")
    public Result<Boolean> batchDeleteChats(@RequestBody List<String> ids) {
        log.info("管理平台-批量删除AI对话: ids={}", ids);
        return Result.success(aiChatService.batchDeleteChats(ids));
    }
    
    /**
     * 管理平台-获取AI对话统计数据
     */
    @Log(description = "管理平台-获取AI对话统计数据", operationType = OperationTypeEnum.QUERY)
    @Operation(summary = "管理平台-获取AI对话统计数据")
    @GetMapping("/getChatStats")
    public Result<Map<String, Object>> getChatStats() {
        log.info("管理平台-获取AI对话统计数据");
        Map<String, Object> stats = aiChatService.getChatStats();
        return Result.success(stats);
    }
    
    /**
     * 管理平台-修改对话状态
     */
    @Log(description = "管理平台-修改对话状态", operationType = OperationTypeEnum.UPDATE)
    @Operation(summary = "管理平台-修改对话状态")
    @PutMapping("/updateChatStatus/{chatId}")
    public Result<Boolean> updateChatStatus(@PathVariable String chatId, @RequestParam Integer status) {
        log.info("管理平台-修改对话状态: chatId={}, status={}", chatId, status);
        return Result.success(aiChatService.updateChatStatus(chatId, status));
    }
} 